{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from dataclasses import dataclass\n",
    "\n",
    "@dataclass\n",
    "class Point:\n",
    "    x: int\n",
    "    y: int\n",
    "\n",
    "\n",
    "@dataclass\n",
    "class DataTrainingArguments:\n",
    "    \"\"\"\n",
    "    Arguments pertaining to what data we are going to input our model for training and eval.\n",
    "    \"\"\"\n",
    "\n",
    "    dataset_name: Optional[str] = field(\n",
    "        default=None, metadata={\"help\": \"The name of the dataset to use (via the datasets library).\"}\n",
    "    )\n",
    "    dataset_config_name: Optional[str] = field(\n",
    "        default=None, metadata={\"help\": \"The configuration name of the dataset to use (via the datasets library).\"}\n",
    "    )\n",
    "    text_column: Optional[str] = field(\n",
    "        default=None,\n",
    "        metadata={\"help\": \"The name of the column in the datasets containing the full texts (for summarization).\"},\n",
    "    )\n",
    "    summary_column: Optional[str] = field(\n",
    "        default=None,\n",
    "        metadata={\"help\": \"The name of the column in the datasets containing the summaries (for summarization).\"},\n",
    "    )\n",
    "    train_file: Optional[str] = field(\n",
    "        default=None, metadata={\"help\": \"The input training data file (a jsonlines or csv file).\"}\n",
    "    )\n",
    "    validation_file: Optional[str] = field(\n",
    "        default=None,\n",
    "        metadata={\n",
    "            \"help\": \"An optional input evaluation data file to evaluate the metrics (rouge) on \"\n",
    "            \"(a jsonlines or csv file).\"\n",
    "        },\n",
    "    )\n",
    "    test_file: Optional[str] = field(\n",
    "        default=None,\n",
    "        metadata={\n",
    "            \"help\": \"An optional input test data file to evaluate the metrics (rouge) on \" \"(a jsonlines or csv file).\"\n",
    "        },\n",
    "    )\n",
    "    overwrite_cache: bool = field(\n",
    "        default=False, metadata={\"help\": \"Overwrite the cached training and evaluation sets\"}\n",
    "    )\n",
    "    preprocessing_num_workers: Optional[int] = field(\n",
    "        default=None,\n",
    "        metadata={\"help\": \"The number of processes to use for the preprocessing.\"},\n",
    "    )\n",
    "    max_source_length: Optional[int] = field(\n",
    "        default=1024,\n",
    "        metadata={\n",
    "            \"help\": \"The maximum total input sequence length after tokenization. Sequences longer \"\n",
    "            \"than this will be truncated, sequences shorter will be padded.\"\n",
    "        },\n",
    "    )\n",
    "    max_target_length: Optional[int] = field(\n",
    "        default=128,\n",
    "        metadata={\n",
    "            \"help\": \"The maximum total sequence length for target text after tokenization. Sequences longer \"\n",
    "            \"than this will be truncated, sequences shorter will be padded.\"\n",
    "        },\n",
    "    )\n",
    "    val_max_target_length: Optional[int] = field(\n",
    "        default=None,\n",
    "        metadata={\n",
    "            \"help\": \"The maximum total sequence length for validation target text after tokenization. Sequences longer \"\n",
    "            \"than this will be truncated, sequences shorter will be padded. Will default to `max_target_length`.\"\n",
    "            \"This argument is also used to override the ``max_length`` param of ``model.generate``, which is used \"\n",
    "            \"during ``evaluate`` and ``predict``.\"\n",
    "        },\n",
    "    )\n",
    "    pad_to_max_length: bool = field(\n",
    "        default=False,\n",
    "        metadata={\n",
    "            \"help\": \"Whether to pad all samples to model maximum sentence length. \"\n",
    "            \"If False, will pad the samples dynamically when batching to the maximum length in the batch. More \"\n",
    "            \"efficient on GPU but very bad for TPU.\"\n",
    "        },\n",
    "    )\n",
    "    max_train_samples: Optional[int] = field(\n",
    "        default=None,\n",
    "        metadata={\n",
    "            \"help\": \"For debugging purposes or quicker training, truncate the number of training examples to this \"\n",
    "            \"value if set.\"\n",
    "        },\n",
    "    )\n",
    "    max_val_samples: Optional[int] = field(\n",
    "        default=None,\n",
    "        metadata={\n",
    "            \"help\": \"For debugging purposes or quicker training, truncate the number of validation examples to this \"\n",
    "            \"value if set.\"\n",
    "        },\n",
    "    )\n",
    "    max_test_samples: Optional[int] = field(\n",
    "        default=None,\n",
    "        metadata={\n",
    "            \"help\": \"For debugging purposes or quicker training, truncate the number of test examples to this \"\n",
    "            \"value if set.\"\n",
    "        },\n",
    "    )\n",
    "    num_beams: Optional[int] = field(\n",
    "        default=None,\n",
    "        metadata={\n",
    "            \"help\": \"Number of beams to use for evaluation. This argument will be passed to ``model.generate``, \"\n",
    "            \"which is used during ``evaluate`` and ``predict``.\"\n",
    "        },\n",
    "    )\n",
    "    ignore_pad_token_for_loss: bool = field(\n",
    "        default=True,\n",
    "        metadata={\n",
    "            \"help\": \"Whether to ignore the tokens corresponding to padded labels in the loss computation or not.\"\n",
    "        },\n",
    "    )\n",
    "    source_prefix: Optional[str] = field(\n",
    "        default=None, metadata={\"help\": \"A prefix to add before every source text (useful for T5 models).\"}\n",
    "    )\n",
    "\n",
    "    def __post_init__(self):\n",
    "        if self.dataset_name is None and self.train_file is None and self.validation_file is None:\n",
    "            raise ValueError(\"Need either a dataset name or a training/validation file.\")\n",
    "        else:\n",
    "            if self.train_file is not None:\n",
    "                extension = self.train_file.split(\".\")[-1]\n",
    "                assert extension in [\"csv\", \"json\"], \"`train_file` should be a csv or a json file.\"\n",
    "            if self.validation_file is not None:\n",
    "                extension = self.validation_file.split(\".\")[-1]\n",
    "                assert extension in [\"csv\", \"json\"], \"`validation_file` should be a csv or a json file.\"\n",
    "        if self.val_max_target_length is None:\n",
    "            self.val_max_target_length = self.max_target_length"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from dataclasses import dataclass\n",
    "\n",
    "@dataclass\n",
    "class Person:\n",
    "    name: str\n",
    "    age: int\n",
    "    friends: list[str]\n",
    "\n",
    "bob: Person = Person('Bob', 29, ['Luigi', 'James'])\n",
    "print(bob)\n",
    "\n",
    "class Person:\n",
    "    def __init__(self, name: str, age: int, friends: list[str]) -> None:\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "        self.friends = friends"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python中的数据类(dataclass)的五个很酷的功能。\n",
    "首先是创建数据类非常容易，并且会自动覆盖初始化器。\n",
    "其次是数据类的字符串表示形式更容易阅读。\n",
    "第三个功能是数据类可以按顺序组织数据类，不需要设置任何比较方法。\n",
    "第四个功能是数据类可以是不可变的，如果不想在脚本执行期间更改类中的任何内容。\n",
    "最后一个功能是数据类可以轻松地添加计算属性。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 参数顺序的约定\n",
    "from dataclasses import dataclass\n",
    "\n",
    "@dataclass(order=True)\n",
    "class Person:\n",
    "    name: str\n",
    "    age: int\n",
    "    friends: list[str]\n",
    "\n",
    "bob: Person = Person('Bob', 29, ['Luigi', 'James'])\n",
    "james: Person = Person('James', 25, ['Bob', 'Luigi'])\n",
    "mario: Person = Person('Mario', 30, [])\n",
    "\n",
    "print(bob)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 非常重要的是,这种dataclass经过初始化之后成员就不可以更改了,imuutibale\n",
    "# 我们给出一些具体的例子\n",
    "@dataclass\n",
    "class RegNetCfg:\n",
    "    depth: int = 21\n",
    "    w0: int = 80\n",
    "    wa: float = 42.63\n",
    "    wm: float = 2.66\n",
    "    group_size: int = 24\n",
    "    bottle_ratio: float = 1.\n",
    "    se_ratio: float = 0.\n",
    "    stem_width: int = 32\n",
    "    downsample: Optional[str] = 'conv1x1'\n",
    "    linear_out: bool = False\n",
    "    preact: bool = False\n",
    "    num_features: int = 0\n",
    "    act_layer: Union[str, Callable] = 'relu'\n",
    "    norm_layer: Union[str, Callable] = 'batchnorm'\n"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
